package com.atguigu.tingshu.order.strategy.impl;

import com.atguigu.tingshu.album.client.AlbumFeignClient;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.utils.ThrowUtil;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.order.strategy.OrderBuildStrategy;
import com.atguigu.tingshu.user.client.UserFeignClient;
import com.atguigu.tingshu.vo.order.OrderDerateVo;
import com.atguigu.tingshu.vo.order.OrderDetailVo;
import com.atguigu.tingshu.vo.order.OrderInfoVo;
import com.atguigu.tingshu.vo.order.TradeVo;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 声音订单构建策略
 */
@Slf4j
@Component
public class TrackOrderBuildStrategy implements OrderBuildStrategy {

    @Autowired
    private AlbumFeignClient albumFeignClient;

    @Autowired
    private UserFeignClient userFeignClient;

    @Override
    public OrderInfoVo buildOrderInfo(TradeVo tradeVo, Long userId) {
        Long trackId = tradeVo.getItemId();
        Integer trackCount = tradeVo.getTrackCount();
        log.info("构建声音订单信息 - userId: {}, trackId: {}, trackCount: {}", userId, trackId, trackCount);

        // 1. 参数校验
        ThrowUtil.throwIf(trackCount == null || trackCount <= 0, "购买集数必须大于0");

        // 2. 查询当前声音信息
        TrackInfo currentTrack = albumFeignClient.getTrackInfo(trackId).getData();
        ThrowUtil.throwIf(currentTrack == null, "声音不存在");

        // 3. 查询专辑信息
        AlbumInfo albumInfo = albumFeignClient.getAlbumInfo(currentTrack.getAlbumId()).getData();
        ThrowUtil.throwIf(albumInfo == null, "专辑不存在");

        // 4. 查询当前声音及之后的所有声音
        List<TrackInfo> afterTracks = albumFeignClient.getTracksFromOrderNum(
                currentTrack.getAlbumId(), currentTrack.getOrderNum()).getData();
        ThrowUtil.throwIf(afterTracks == null || afterTracks.isEmpty(), "没有可购买的声音");
        log.info("当前声音及之后的声音总数: {}", afterTracks.size());

        // 5. 查询用户已购买的声音
        List<Long> afterTrackIds = afterTracks.stream().map(TrackInfo::getId).toList();
        Map<Long, Integer> userPaidMap = new HashMap<>();
        if (!afterTrackIds.isEmpty()) {
            var result = userFeignClient.userIsPaidTrack(userId, currentTrack.getAlbumId(), afterTrackIds);
            if (result != null && result.getData() != null) {
                userPaidMap = result.getData();
            }
        }

        // 6. 过滤掉已购买的声音，得到未购买列表
        List<TrackInfo> unpaidTracks = new ArrayList<>();
        for (TrackInfo track : afterTracks) {
            if (userPaidMap.get(track.getId()) == null || userPaidMap.get(track.getId()) == 0) {
                unpaidTracks.add(track);
            }
        }
        ThrowUtil.throwIf(unpaidTracks.isEmpty(), "没有可购买的声音，您已购买过该声音及之后的所有声音");
        log.info("当前声音之后未购买的声音数量: {}", unpaidTracks.size());

        // 7. 验证购买集数是否合法
        ThrowUtil.throwIf(trackCount > unpaidTracks.size(),
                "购买集数不能超过可购买的声音数量，当前可购买" + unpaidTracks.size() + "集");

        // 8. 取前n集未购买的声音
        List<TrackInfo> toBuyTracks = unpaidTracks.subList(0, trackCount);
        log.info("实际购买声音ID列表: {}", toBuyTracks.stream().map(TrackInfo::getId).toList());

        // 9. 查询用户信息，判断是否为VIP
        UserInfoVo userInfoVo = userFeignClient.getUserInfoVo(userId).getData();
        boolean isVip = userInfoVo != null && userInfoVo.getIsVip() != null && userInfoVo.getIsVip() == 1;
        log.info("用户VIP状态 - userId: {}, isVip: {}", userId, isVip);

        // 10. 构建OrderInfoVo
        OrderInfoVo orderInfoVo = new OrderInfoVo();
        orderInfoVo.setItemType(SystemConstant.ORDER_ITEM_TYPE_TRACK);

        // 11. 构建声音订单明细
        List<OrderDetailVo> orderDetailVoList = new ArrayList<>();
        for (TrackInfo track : toBuyTracks) {
            OrderDetailVo orderDetailVo = new OrderDetailVo();
            orderDetailVo.setItemId(track.getId());
            orderDetailVo.setItemName(track.getTrackTitle());
            orderDetailVo.setItemUrl(track.getCoverUrl());
            orderDetailVo.setItemPrice(albumInfo.getPrice());
            orderDetailVoList.add(orderDetailVo);
        }
        orderInfoVo.setOrderDetailVoList(orderDetailVoList);

        // 12. 计算订单金额和折扣信息
        BigDecimal discountRate = isVip ? albumInfo.getVipDiscount() : albumInfo.getDiscount();
        BigDecimal originalAmount = albumInfo.getPrice().multiply(new BigDecimal(trackCount));

        BigDecimal orderAmount;
        if (discountRate != null && discountRate.compareTo(new BigDecimal("-1")) != 0) {
            orderAmount = originalAmount.multiply(discountRate).setScale(2, RoundingMode.HALF_UP);
        } else {
            orderAmount = originalAmount;
        }

        BigDecimal totalDerateAmount = originalAmount.subtract(orderAmount);
        orderInfoVo.setOriginalAmount(originalAmount);
        orderInfoVo.setDerateAmount(totalDerateAmount);
        orderInfoVo.setOrderAmount(orderAmount);

        // 13. 订单减免明细列表
        List<OrderDerateVo> orderDerateVoList = new ArrayList<>();
        if (totalDerateAmount.compareTo(BigDecimal.ZERO) > 0) {
            BigDecimal singleDerateAmount;
            if (discountRate != null && discountRate.compareTo(new BigDecimal("-1")) != 0) {
                singleDerateAmount = albumInfo.getPrice()
                        .multiply(BigDecimal.ONE.subtract(discountRate))
                        .setScale(2, RoundingMode.HALF_UP);
            } else {
                singleDerateAmount = BigDecimal.ZERO;
            }

            for (TrackInfo track : toBuyTracks) {
                if (singleDerateAmount.compareTo(BigDecimal.ZERO) > 0) {
                    OrderDerateVo orderDerateVo = new OrderDerateVo();
                    orderDerateVo.setDerateType(SystemConstant.ORDER_DERATE_ALBUM_DISCOUNT);
                    orderDerateVo.setDerateAmount(singleDerateAmount);
                    orderDerateVo.setRemarks((isVip ? "VIP专享折扣" : "专辑折扣") + " - " + track.getTrackTitle());
                    orderDerateVoList.add(orderDerateVo);
                }
            }
        }
        orderInfoVo.setOrderDerateVoList(orderDerateVoList);

        log.info("声音订单信息构建完成 - trackId: {}, trackCount: {}, isVip: {}, orderAmount: {}, toBuyTrackIds: {}",
                trackId, trackCount, isVip, orderAmount, toBuyTracks.stream().map(TrackInfo::getId).toList());
        return orderInfoVo;
    }

    @Override
    public String getOrderType() {
        return SystemConstant.ORDER_ITEM_TYPE_TRACK;
    }
}
